package com.example.database.controller;

import com.example.database.config.EvictableDataSource;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
import com.zaxxer.hikari.pool.HikariPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.stream.IntStream;

/**
 * @author zpMeng
 * @since 9/30/2025
 */
@Slf4j
@Controller
@RequiredArgsConstructor
public class PoolStatController {

    private final JdbcTemplate jdbcTemplate;

    @Scheduled(initialDelay = 1000L, fixedDelay = 1000L)
    private void printPoolStat() {
        EvictableDataSource dataSource1 = (EvictableDataSource) jdbcTemplate.getDataSource();

        HikariPoolMXBean hikariPoolMXBean = dataSource1.getHikariPoolMXBean();
        int total = hikariPoolMXBean.getTotalConnections();
        int active = hikariPoolMXBean.getActiveConnections();
        int idle = hikariPoolMXBean.getIdleConnections();

        log.info("total: {} -- active: {} -- idle: {}", total, active, idle);
    }

    @Scheduled(fixedDelay = 2000L)
    private void executeSql() {
        String sql = "select * from information_schema.tables where table_schema = 'public'";
        IntStream
                .rangeClosed(1, 10)
                .parallel()
                .forEach(i -> {
                    try {
                        HikariDataSource dataSource = (HikariDataSource) jdbcTemplate.getDataSource();
                        HikariPool hikariPool = (HikariPool) dataSource.getHikariPoolMXBean();

                        jdbcTemplate.execute((ConnectionCallback<Void>) con -> {

                            PreparedStatement preparedStatement = con.prepareStatement(sql);
                            preparedStatement.execute();
                            return null;
                        });

                        Connection connection = dataSource.getConnection();
                        //dataSource.evictConnection(connection);
                        connection.close();

                    } catch (Exception e) {

                    }


                });
    }

}
